/*******************************************************************************
 * Copyright (C) 2013 Jeremy Brodt and Kevin Gillespie
 * Description: Task Timer
 *         $Id: tick.c 25 2014-04-13 22:55:26Z brodtj1212@gmail.com $
 *******************************************************************************
 */

#include "maxq_config.h"
#include "comm/maxq_comm.h"
#include "tick.h"

/***** Definitions *****/
#define WUT_FREQ          (XTAL_FREQ / 1024)
#define TICKS_PER_SECOND  40   // 25 ms
#define WUT_VALUE         (WUT_FREQ / TICKS_PER_SECOND)

/***** Global Data *****/
volatile int flag_25ms;
volatile int flag_50ms;
volatile int flag_75ms;
volatile int flag_100ms;
volatile int flag_200ms;
volatile int flag_400ms;
volatile unsigned int tick_cnt;
volatile int flag_alarm;
int tick_alarm_cnt;
void (*tick_callback)(void);

/****************************************************************************/
void tick_init()
{
  WUT = WUT_VALUE; // set timer value
  WUTC = 0x01;  // start timer
  tick_callback = NULL;
  tick_alarm_cnt = -1;
}

/****************************************************************************/
unsigned int tick_gettime()
{
  return tick_cnt / TICKS_PER_SECOND;
}

/****************************************************************************/
#pragma vector = 7
__interrupt void tick_isr(void)
{
  static int cnt25 = 0;
  PO3 &= ~2;
  WUTC = 0; // clear flag and disable timer
  WUT = WUT_VALUE; // set timer value
  WUTC = 0x01;  // start timer
  tick_cnt++;
  flag_25ms = 1;
  cnt25++;
  if ((tick_cnt & 0x1) == 0)
    flag_50ms = 1;
  if (cnt25 == 3) {
    cnt25 = 0;
    flag_75ms = 1;
  }
  if ((tick_cnt & 0x3) == 0)
    flag_100ms = 1;
  if ((tick_cnt & 0x7) == 0)
    flag_200ms = 1;
  if ((tick_cnt & 0xF) == 0)
    flag_400ms = 1;
  PO3 |= 2;

  if (tick_alarm_cnt >= 0) {
    tick_alarm_cnt--;
  }

  if (tick_alarm_cnt == 0) {
    flag_alarm = 1;
  }
}

/****************************************************************************/
void tick_alarm_set(unsigned int ms, void (*func)(void))
{
  tick_callback = func;
  tick_alarm_cnt = (ms + 24) / 25;
}

/****************************************************************************/
void tick_alarm_clr(void)
{
  tick_callback = NULL;
  tick_alarm_cnt = -1;
  flag_alarm = 0;
}
